package net.linku.annotation.change.service.impl;

import cn.hutool.core.util.ReflectUtil;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.baomidou.mybatisplus.extension.service.IService;
import net.linku.annotation.ChangeRecordLog;
import net.linku.annotation.change.service.ContentParser;
import net.linku.annotation.change.service.IChangeService;

import java.io.Serializable;
import java.util.Objects;

/**
 * 默认内容解析实现类，用于根据方法参数或ID获取变更记录的数据。
 *
 * <p>该类实现了 {@link ContentParser} 接口，提供了根据给定的 ID 查询数据的方法，
 * 以及根据方法参数直接获取数据的方法。它支持从 {@link IService} 或 {@link IChangeService}
 * 中获取数据。</p>
 *
 */
@Component
@SuppressWarnings("all")
public class DefaultContentParse implements ContentParser {

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 根据切点信息和变更记录注解获取结果。
     *
     * @param joinPoint 切点信息，包含方法参数
     * @param changeRecordLog 变更记录注解，包含服务类和ID字段名称等信息
     * @return 获取的数据结果
     */
    @Override
    public Object getResult(JoinPoint joinPoint, ChangeRecordLog changeRecordLog) {
        // 使用方法参数（通常为第一个参数）获取数据
        return getResult(joinPoint.getArgs()[0], changeRecordLog);
    }

    /**
     * 根据对象及变更记录注解获取结果。
     *
     * @param obj 方法参数对象
     * @param changeRecordLog 变更记录注解，包含服务类和ID字段名称等信息
     * @return 获取的数据结果
     */
    @Override
    public Object getResult(Object obj, ChangeRecordLog changeRecordLog) {
        // 从对象中获取ID
        Object id = ReflectUtil.getFieldValue(obj, changeRecordLog.keyId());
        // 根据ID查询数据
        return getResultById(id, changeRecordLog);
    }

    /**
     * 根据ID和变更记录注解获取数据结果。
     *
     * @param modifyId 修改记录的ID
     * @param changeRecordLog 变更记录注解，包含服务类和ID字段名称等信息
     * @return 获取的数据结果，如果ID为空则返回null
     */
    @Override
    public Object getResultById(Object modifyId, ChangeRecordLog changeRecordLog) {
        // 如果 ID 为空，直接返回 null
        if (Objects.isNull(modifyId)) {
            return null;
        }

        // 获取服务类
        Class<?> cls = changeRecordLog.serviceclass();
        if (cls == null) {
            throw new IllegalArgumentException("服务类为空");
        }

        // 根据服务类类型获取数据
        if (IService.class.isAssignableFrom(cls)) {
            IService<?> service = (IService<?>) applicationContext.getBean(cls);
            if (service == null) {
                throw new RuntimeException("未找到类型为 " + cls.getName() + " 的 Service bean");
            }
            return service.getById((Serializable) modifyId);
        }

        if (IChangeService.class.isAssignableFrom(cls)) {
            IChangeService service = (IChangeService) applicationContext.getBean(cls);
            if (service == null) {
                throw new RuntimeException("未找到类型为 " + cls.getName() + " 的 ChangeService bean");
            }
            return service.queryDetail((Serializable) modifyId);
        }

        // 如果服务类类型不匹配，则返回 null
        throw new IllegalArgumentException("服务类 " + cls.getName() + " 不是支持的类型");
    }

}
